<template>
  <el-drawer :model-value="visible" size="720px" :with-header="true" @close="onClose">
    <template #header>
      <div class="drawer-header">
        <span class="node-icon" v-if="nodeIconUnicode" :style="{ color: nodeIconColor }">{{ nodeIconUnicode }}</span>
        <span class="title">API 工具</span>
      </div>
    </template>

    <div class="drawer-body">
      <el-form :model="form" label-position="left" class="name-form">
        <el-form-item label="名称">
          <el-input v-model="form.name" maxlength="10" placeholder="请输入名称（最多10字）" />
        </el-form-item>
      </el-form>
      <div class="req-line">
        <el-select v-model="form.method" class="method-select" @change="emitSave">
          <el-option label="GET" value="GET" />
          <el-option label="POST" value="POST" />
          <el-option label="PUT" value="PUT" />
          <el-option label="DELETE" value="DELETE" />
        </el-select>
        <el-input v-model="form.url" placeholder="https://api.example.com/path" @input="emitSave" />
      </div>

      <el-tabs v-model="activeTab" class="tabs">
        <el-tab-pane label="Params" name="params">
          <div class="kv-toolbar">
            <el-button type="primary" link @click="addParam">新增参数</el-button>
          </div>
          <div class="kv-list">
            <div class="kv-row" v-for="(p, i) in form.params" :key="i">
              <el-checkbox v-model="p.enabled" @change="emitSave" />
              <el-input v-model="p.key" placeholder="Key" @input="emitSave" />
              <el-input v-model="p.value" placeholder="Value" @input="emitSave" />
              <el-button circle size="small" type="danger" class="del-btn" @click="removeParam(i)"><el-icon><Close /></el-icon></el-button>
            </div>
          </div>
        </el-tab-pane>

        <el-tab-pane label="Headers" name="headers">
          <div class="kv-toolbar">
            <el-button type="primary" link @click="addHeader">新增请求头</el-button>
          </div>
          <div class="kv-list">
            <div class="kv-row" v-for="(h, i) in form.headers" :key="i">
              <el-checkbox v-model="h.enabled" @change="emitSave" />
              <el-input v-model="h.key" placeholder="Header" @input="emitSave" />
              <el-input v-model="h.value" placeholder="Value" @input="emitSave" />
              <el-button circle size="small" type="danger" class="del-btn" @click="removeHeader(i)"><el-icon><Close /></el-icon></el-button>
            </div>
          </div>
        </el-tab-pane>

        <el-tab-pane label="Body" name="body">
          <div class="body-type-line">
            <span>Body 类型：</span>
            <el-radio-group v-model="form.body.type" @change="emitSave">
              <el-radio-button label="none">none</el-radio-button>
              <el-radio-button label="json">JSON</el-radio-button>
              <el-radio-button label="form-data">form-data</el-radio-button>
              <el-radio-button label="x-www-form-urlencoded">x-www-form-urlencoded</el-radio-button>
              <el-radio-button label="raw">raw</el-radio-button>
            </el-radio-group>
          </div>

          <div v-if="form.body.type === 'json'" class="json-editor">
            <el-input
              v-model="form.body.jsonText"
              type="textarea"
              :autosize="{ minRows: 10, maxRows: 16 }"
              placeholder='{"key": "value"}'
              @input="emitSave"
            />
            <div class="json-tools">
              <el-button size="small" @click="beautifyJson">格式化</el-button>
              <el-button size="small" type="warning" @click="validateJson">校验</el-button>
            </div>
          </div>

          <div v-else-if="form.body.type === 'form-data'" class="kv-list">
            <div class="kv-toolbar">
              <el-button type="primary" link @click="addFormData">新增字段</el-button>
            </div>
            <div class="kv-row kv-row--formdata" v-for="(f, i) in form.body.formData" :key="i">
              <el-checkbox v-model="f.enabled" @change="emitSave" />
              <el-input v-model="f.key" placeholder="Key" @input="emitSave" />
              <el-select v-model="f.type" class="kv-type" @change="emitSave">
                <el-option label="Text" value="text" />
                <el-option label="File" value="file" />
              </el-select>
              <el-input v-model="f.value" placeholder="Value 或文件名" @input="emitSave" />
              <el-button circle size="small" type="danger" class="del-btn" @click="removeFormData(i)"><el-icon><Close /></el-icon></el-button>
            </div>
          </div>

          <div v-else-if="form.body.type === 'x-www-form-urlencoded'" class="kv-list">
            <div class="kv-toolbar">
              <el-button type="primary" link @click="addUrlEncoded">新增字段</el-button>
            </div>
            <div class="kv-row" v-for="(u, i) in form.body.urlencoded" :key="i">
              <el-checkbox v-model="u.enabled" @change="emitSave" />
              <el-input v-model="u.key" placeholder="Key" @input="emitSave" />
              <el-input v-model="u.value" placeholder="Value" @input="emitSave" />
              <el-button circle size="small" type="danger" class="del-btn" @click="removeUrlEncoded(i)"><el-icon><Close /></el-icon></el-button>
            </div>
          </div>

          <div v-else-if="form.body.type === 'raw'" class="json-editor">
            <el-input
              v-model="form.body.rawText"
              type="textarea"
              :autosize="{ minRows: 10, maxRows: 16 }"
              placeholder="Raw body"
              @input="emitSave"
            />
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
  </el-drawer>
</template>

<script>
import { defineComponent, reactive, watch, computed, ref } from 'vue'
import { Close } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { componentRegistry } from '@/components/WorkFlow/core/ComponentRegistry'

export default defineComponent({
  name: 'ApiDrawer',
  components: { Close },
  props: {
    visible: { type: Boolean, default: false },
    nodeData: { type: Object, default: null }
  },
  emits: ['save', 'close'],
  setup(props, { emit }) {
    const activeTab = ref('params')
    const form = reactive({
      name: '',
      method: 'GET',
      url: '',
      params: [],
      headers: [],
      body: {
        type: 'none',
        jsonText: '',
        formData: [],
        urlencoded: [],
        rawText: ''
      }
    })

    const nodeIconUnicode = computed(() => {
      const t = props.nodeData?.type
      const cfg = t ? componentRegistry.getNodeConfig(t) : null
      return cfg?.iconUnicode || ''
    })
    const nodeIconColor = computed(() => {
      const t = props.nodeData?.type
      const cfg = t ? componentRegistry.getNodeConfig(t) : null
      return props.nodeData?.color || cfg?.color || '#333333'
    })

    /**
     * 初始化表单数据
     * @returns {void}
     */
    const initForm = () => {
      const d = props.nodeData || {}
      const api = d.api || {}
      form.name = (d.name || '').toString().slice(0, 10)
      form.method = api.method || 'GET'
      form.url = api.url || ''
      form.params = Array.isArray(api.params) ? api.params.map(x => ({...x})) : []
      form.headers = Array.isArray(api.headers) ? api.headers.map(x => ({...x})) : []
      form.body = {
        type: api.body?.type || 'none',
        jsonText: api.body?.jsonText || '',
        formData: Array.isArray(api.body?.formData) ? api.body.formData.map(x => ({...x})) : [],
        urlencoded: Array.isArray(api.body?.urlencoded) ? api.body.urlencoded.map(x => ({...x})) : [],
        rawText: api.body?.rawText || ''
      }
    }

    /**
     * 上抛实时保存
     * @returns {void}
     */
    const emitSave = () => {
      emit('save', { api: JSON.parse(JSON.stringify(form)) })
    }

    /**
     * 新增/删除操作集
     * @returns {void}
     */
    const addParam = () => { form.params.push({ enabled: true, key: '', value: '' }); emitSave() }
    const removeParam = (i) => { form.params.splice(i, 1); emitSave() }
    const addHeader = () => { form.headers.push({ enabled: true, key: '', value: '' }); emitSave() }
    const removeHeader = (i) => { form.headers.splice(i, 1); emitSave() }
    const addFormData = () => { form.body.formData.push({ enabled: true, key: '', type: 'text', value: '' }); emitSave() }
    const removeFormData = (i) => { form.body.formData.splice(i, 1); emitSave() }
    const addUrlEncoded = () => { form.body.urlencoded.push({ enabled: true, key: '', value: '' }); emitSave() }
    const removeUrlEncoded = (i) => { form.body.urlencoded.splice(i, 1); emitSave() }

    /**
     * JSON 美化
     * @returns {void}
     */
    const beautifyJson = () => {
      try {
        const obj = JSON.parse(form.body.jsonText || '{}')
        form.body.jsonText = JSON.stringify(obj, null, 2)
        emitSave()
      } catch (e) {
        ElMessage.error('JSON 格式错误')
      }
    }

    /**
     * JSON 校验
     * @returns {void}
     */
    const validateJson = () => {
      try {
        JSON.parse(form.body.jsonText || '{}')
        ElMessage.success('JSON 校验通过')
      } catch (e) {
        ElMessage.error('JSON 格式错误')
      }
    }

    watch(() => props.nodeData, () => initForm(), { immediate: true })
    watch(form, () => emitSave(), { deep: true })

    const onClose = () => {
      const name = (form.name || '').toString().slice(0, 10)
      if (name) emit('save', { name })
      emit('close')
    }

    return {
      visible: props.visible,
      form,
      activeTab,
      addParam,
      removeParam,
      addHeader,
      removeHeader,
      addFormData,
      removeFormData,
      addUrlEncoded,
      removeUrlEncoded,
      beautifyJson,
      validateJson,
      emitSave,
      onClose,
      nodeIconUnicode,
      nodeIconColor
    }
  }
})
</script>

<style scoped>
.drawer-header { display: flex; align-items: center; gap: 8px; }
.node-icon { font-family: iconfont; font-size: 20px; line-height: 1; }
.title { font-size: 16px; font-weight: 600; }
.drawer-body { padding: 8px 4px 16px 4px; }
.name-form :deep(.el-form-item__label) { width: auto !important; text-align: left; padding-right: 8px; }
.req-line { display: grid; grid-template-columns: 140px 1fr; gap: 8px; margin-bottom: 8px; align-items: center; }
.method-select :deep(.el-select__selection) { font-weight: 600; }
.tabs { margin-top: 4px; }
.kv-toolbar { display: flex; justify-content: flex-end; margin-bottom: 6px; }
.kv-list { display: flex; flex-direction: column; gap: 8px; }
.kv-row { display: grid; grid-template-columns: 24px 1fr 1fr 44px; gap: 8px; align-items: center; }
.kv-type { width: 120px; }
.json-editor { margin-top: 8px; }
.json-tools { margin-top: 6px; display: flex; gap: 8px; }
.del-btn { padding: 2px; height: 24px; }
.del-btn :deep(.el-icon) { font-size: 14px; }
.kv-row--formdata { grid-template-columns: 24px 1fr 120px 1fr 44px; }
.body-type-line { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
.body-type-line { display: flex; align-items: center; gap: 8px; }
</style>
